package com.ellecity06.common.utils

import android.content.ContentValues
import android.content.Context
import android.graphics.*
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Environment
import android.provider.MediaStore
import android.view.View
import android.widget.ImageView
import androidx.core.os.EnvironmentCompat
import com.ellecity06.common.ktx.dp2px
import com.huawei.hms.hmsscankit.ScanUtil
import com.huawei.hms.hmsscankit.WriterException
import com.huawei.hms.ml.scan.HmsBuildBitmapOption
import com.huawei.hms.ml.scan.HmsScan
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.FileDescriptor
import java.text.SimpleDateFormat
import java.util.*


class BitmapUtils {
    companion object {
        private val mCanvas: Canvas by lazy { Canvas() }
        fun createBitmapFromView(view: View): Bitmap? {
            return createBitmapFromView(view, 1f)
        }

        fun bmpToByteArray(bmp: Bitmap, needRecycle: Boolean): ByteArray? {
            val output = ByteArrayOutputStream()
            bmp.compress(Bitmap.CompressFormat.PNG, 100, output)
            if (needRecycle) {
                bmp.recycle()
            }
            val result = output.toByteArray()
            try {
                output.close()
            } catch (e: java.lang.Exception) {
                e.printStackTrace()
            }
            return result
        }

        /**
         * 创建图片地址uri,用于保存拍照后的照片 Android 10以后使用这种方法
         */
        fun createImageUri(): Uri? {
            val status = Environment.getExternalStorageState()
            // 判断是否有SD卡,优先使用SD卡存储,当没有SD卡时使用手机存储
            return if (status == Environment.MEDIA_MOUNTED) {
                appContext.getContentResolver().insert(
                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI, ContentValues()
                )
            } else {
                appContext.getContentResolver().insert(
                    MediaStore.Images.Media.INTERNAL_CONTENT_URI, ContentValues()
                )
            }
        }

        /**
         * 创建保存图片的文件
         */
        fun createImageFile(): File? {
            val imageName = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
            val storageDir: File? = appContext.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
            if (storageDir?.exists() == false) {
                storageDir?.mkdir()
            }

            val tempFile = File(storageDir, imageName)
            return if (Environment.MEDIA_MOUNTED != EnvironmentCompat.getStorageState(tempFile)) {
                null
            } else tempFile
        }


        fun getBitmapFromUri(context: Context, uri: Uri?): Bitmap? {
            try {
                val parcelFileDescriptor = context.contentResolver.openFileDescriptor(
                    uri!!, "r"
                )
                val fileDescriptor: FileDescriptor = parcelFileDescriptor!!.fileDescriptor
                val image = BitmapFactory.decodeFileDescriptor(fileDescriptor)
                parcelFileDescriptor.close()
                return image
            } catch (e: Exception) {
                e.printStackTrace()
            }
            return null
        }

        fun createBitmapFromView(view: View, scale: Float): Bitmap? {
            if (view is ImageView) {
                val drawable = view.drawable
                if (drawable != null && drawable is BitmapDrawable) {
                    return drawable.bitmap
                }
            }
            view.clearFocus()
            val bitmap = createBitmapSafely(
                (view.width * scale.toInt()),
                view.height * scale.toInt(),
                Bitmap.Config.ARGB_8888,
                1
            )
            if (bitmap != null) {
                synchronized(mCanvas) {
                    val canvas = mCanvas
                    canvas.setBitmap(bitmap)
                    canvas.save()
                    canvas.drawColor(Color.WHITE)
                    canvas.scale(scale, scale)
                    view.draw(canvas)
                    canvas.restore()
                    canvas.setBitmap(null)
                }
            }
            return bitmap
        }


        fun createBitmapSafely(
            width: Int, height: Int, config: Bitmap.Config, retryCount: Int
        ): Bitmap? {
            try {
                return Bitmap.createBitmap(width, height, config)
            } catch (e: Exception) {
                e.printStackTrace()
                if (retryCount > 0) {
                    System.gc()
                    return createBitmapSafely(width, height, config, retryCount)
                }
            }
            return null
        }


        /**
         * View to bitmap.
         *
         * @param view The view.
         * @return bitmap
         */
        fun view2Bitmap(view: View?): Bitmap? {
            if (view == null) return null
            val drawingCacheEnabled = view.isDrawingCacheEnabled
            val willNotCacheDrawing = view.willNotCacheDrawing()
            view.isDrawingCacheEnabled = true
            view.setWillNotCacheDrawing(false)
            var drawingCache = view.drawingCache
            val bitmap: Bitmap
            if (null == drawingCache || drawingCache.isRecycled) {
                view.measure(
                    View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
                    View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
                )
                view.layout(0, 0, view.measuredWidth, view.measuredHeight)
                view.buildDrawingCache()
                drawingCache = view.drawingCache
                if (null == drawingCache || drawingCache.isRecycled) {
                    bitmap = Bitmap.createBitmap(
                        view.measuredWidth, view.measuredHeight, Bitmap.Config.RGB_565
                    )
                    val canvas = Canvas(bitmap)
                    view.draw(canvas)
                } else {
                    bitmap = Bitmap.createBitmap(drawingCache)
                }
            } else {
                bitmap = Bitmap.createBitmap(drawingCache)
            }
            view.setWillNotCacheDrawing(willNotCacheDrawing)
            view.isDrawingCacheEnabled = drawingCacheEnabled
            return bitmap
        }


        /**
         * drawable 转 bitmap
         */
        fun drawable2Bitmap(drawable: Drawable, width: Int = -1, height: Int = -1): Bitmap {

            val intrinsicWidth = if (width == -1) drawable.intrinsicWidth else width
            val intrinsicHeight = if (height == -1) drawable.intrinsicHeight else height
            val bitmap = Bitmap.createBitmap(
                    intrinsicWidth,
                    intrinsicHeight,
                    if (drawable.opacity != PixelFormat.OPAQUE) Bitmap.Config.ARGB_8888 else Bitmap.Config.RGB_565
                )
            val canvas = Canvas(bitmap)
            drawable.setBounds(
                0, 0, intrinsicWidth, intrinsicHeight
            )
            drawable.draw(canvas)
            return bitmap
        }

        /**
         * 创建一个二维码图片
         */
        fun createQrBitmap(content: String, size: Float, logo: Drawable? = null): Bitmap? {
            return try {
                val options = HmsBuildBitmapOption.Creator().setBitmapMargin(3)
                if (logo != null) {
                    val drawable2Bitmap = drawable2Bitmap(logo)
                    options.setQRLogoBitmap(drawable2Bitmap)
                }
                ScanUtil.buildBitmap(
                    content, HmsScan.QRCODE_SCAN_TYPE, size.dp2px(), size.dp2px(), options.create()
                )


            } catch (e: WriterException) {
                null
            }
        }
    }


}